home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2003 November A
/
PCWK1103A.iso
/
ABBYY FineReader 7.0 PRO
/
data1.cab
/
pdf_draw.ps
< prev
next >
Wrap
Text File
|
2002-02-23
|
35KB
|
1,151 lines
% Copyright (C) 1994, 2000 Aladdin Enterprises. All rights reserved.
%
% This software is provided AS-IS with no warranty, either express or
% implied.
%
% This software is distributed under license and may not be copied,
% modified or distributed except as expressly authorized under the terms
% of the license contained in the file LICENSE in this distribution.
%
% For more information about licensing, please refer to
% http://www.ghostscript.com/licensing/. For information on
% commercial licensing, go to http://www.artifex.com/licensing/ or
% contact Artifex Software, Inc., 101 Lucas Valley Road #110,
% San Rafael, CA 94903, U.S.A., +1(415)492-9861.
% $Id: pdf_draw.ps,v 1.36.2.1 2002/02/22 19:45:55 ray Exp $
% pdf_draw.ps
% PDF drawing operations (graphics, text, and images).
/.setlanguagelevel where { pop 2 .setlanguagelevel } if
.currentglobal true .setglobal
/pdfdict where { pop } { /pdfdict 100 dict def } ifelse
GS_PDF_ProcSet begin
pdfdict begin
% For simplicity, we use a single interpretation dictionary for all
% PDF graphics operations, even though this is too liberal.
/drawopdict 100 dict def
% ================================ Graphics ================================ %
% ---------------- Functions ---------------- %
% Note that resolvefunction converts a PDF Function to a PostScript Function;
% resolve*fnproc converts a PDF function to a PostScript procedure.
/fnrdict mark
0 { .resolvefn0 }
2 { }
3 { .resolvefn3 }
4 { .resolvefn4 }
.dicttomark readonly def
/.resolvefn0 {
% Don't lose our place in PDFfile.
PDFfile fileposition exch
dup true resolvestream
% The stream isn't positionable, so read all the data now.
% Stack: filepos fndict stream
1 index /Range oget length 2 idiv 2 index /BitsPerSample oget mul
2 index /Size oget { mul } forall
7 add 8 idiv string
1 index exch readstring pop exch closefile
% Stack: filepos fndict data
exch dup length 1 add dict .copydict
dup /DataSource 4 -1 roll put
exch PDFfile exch setfileposition
} bdef
/.resolvefn3 {
dup length dict .copydict
dup /Bounds 2 copy knownoget { put } { pop pop } ifelse
dup /Encode 2 copy knownoget { put } { pop pop } ifelse
dup /Functions 2 copy oget mark exch dup {
oforce .resolvefn
} forall
counttomark -1 roll astore exch pop put
} bdef
/.resolvefn4 {
PDFfile fileposition exch % filepos fndict
dup true resolvestream % filepos fndict stream
exch dup length dict copy % filepos stream fndict2
dup /Function undef % filepos stream fndict2
exch dup token not {
() /rangecheck cvx signalerror
} if
exch token {
/rangecheck cvx signalerror
} if
% Use .bind to avoid idiom recognition.
.bind
1 index /Function 3 -1 roll put
exch PDFfile exch setfileposition
} bdef
currentdict /tfopdict undef
/.resolvefn { % <fndict> .resolvefn <fndict'>
dup /FunctionType oget //fnrdict exch get exec
} bdef
/resolvefunction { % <fndict> resolvefunction <function>
.resolvefn
DEBUG { (%Function: ) print dup === flush } if
} bdef
/resolvefnproc { % <fndict> resolvefnproc <proc>
resolvefunction .buildfunction
} bdef
/resolveidfnproc { % <fndict> resolveidfnproc <proc>
dup /Identity eq { pop { } } { resolvefnproc } ifelse
} bdef
/resolvedefaultfnproc { % <fndict> <default> resolved'fnproc <proc>
1 index /Default eq { exch pop } { pop resolveidfnproc } ifelse
} bdef
% ---------------- Shadings ---------------- %
/shrdict mark
/ColorSpace {
resolvecolorspace
}
/Function {
dup type /dicttype eq {
resolvefunction
} {
[ exch { oforce resolvefunction } forall ]
} ifelse
}
.dicttomark readonly def
/resolveshading { % <shadingstream> resolveshading <shading>
PDFfile fileposition exch
mark exch {
oforce //shrdict 2 index .knownget { exec } if
} forall .dicttomark
dup /ShadingType get 4 ge {
dup dup true resolvestream
% Make a reusable stream so that the shading doesn't
% reposition PDFfile at unexpected times.
/ReusableStreamDecode filter /DataSource exch put
} if exch PDFfile exch setfileposition
} bdef
/resolvesh { % <shname> resolveshading <shading>
Page /Shading rget {
resolveshading
} {
null
}ifelse
} bdef
% ---------------- Halftones ---------------- %
/spotfunctions mark
/Round {
abs exch abs 2 copy add 1 le {
dup mul exch dup mul add 1 exch sub
} {
1 sub dup mul exch 1 sub dup mul add 1 sub
} ifelse
}
/Diamond {
abs exch abs 2 copy add .75 le {
dup mul exch dup mul add 1 exch sub
} {
2 copy add 1.23 le {
.85 mul add 1 exch sub
} {
1 sub dup mul exch 1 sub dup mul add 1 sub
} ifelse
} ifelse
}
/Ellipse {
abs exch abs 2 copy 3 mul exch 4 mul add 3 sub dup 0 lt {
pop dup mul exch .75 div dup mul add 4 div 1 exch sub
} {
dup 1 gt {
pop 1 exch sub dup mul exch 1 exch sub
.75 div dup mul add 4 div 1 sub
} {
.5 exch sub exch pop exch pop
} ifelse
} ifelse
}
/EllipseA { dup mul .9 mul exch dup mul add 1 exch sub }
/InvertedEllipseA { dup mul .9 mul exch dup mul add 1 sub }
/EllipseB { dup 5 mul 8 div mul exch dup mul exch add sqrt 1 exch sub }
/EllipseC { dup mul .9 mul exch dup mul add 1 exch sub }
/InvertedEllipseC { dup mul .9 mul exch dup mul add 1 sub }
/Line { exch pop abs neg }
/LineX { pop }
/LineY { exch pop }
/Square { abs exch abs 2 copy lt { exch } if pop neg }
/Cross { abs exch abs 2 copy gt { exch } if pop neg }
/Rhomboid { abs exch abs 0.9 mul add 2 div }
/DoubleDot { 2 {360 mul sin 2 div exch } repeat add }
/InvertedDoubleDot { 2 {360 mul sin 2 div exch } repeat add neg }
/SimpleDot { dup mul exch dup mul add 1 exch sub }
/InvertedSimpleDot { dup mul exch dup mul add 1 sub }
/CosineDot { 180 mul cos exch 180 mul cos add 2 div }
/Double { exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add }
/InvertedDouble {
exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add neg
}
.dicttomark readonly def
/htrdict mark
1 { .resolveht1 }
5 { .resolveht5 }
% We don't support types 6, 10, or 16 yet.
.dicttomark readonly def
/.resolveht1 {
mark exch {
oforce
1 index /SpotFunction eq {
dup type /nametype eq
{ //spotfunctions exch get } { resolvefnproc }
ifelse
} {
1 index /TransferFunction eq {
resolveidfnproc
} if
} ifelse
} forall .dicttomark
} bdef
/.resolveht5 {
mark exch {
oforce dup type /dicttype eq { resolvehalftone } if
} forall .dicttomark
} bdef
/resolvehalftone { % <dict> resolvehalftone <halftone>
dup /HalftoneType get //htrdict exch get exec
} bdef
% ---------------- Graphics state management ---------------- %
/cmmatrix matrix def
drawopdict begin
% Graphics state stack
/q { q } def
/Q { Q } def
% Graphics state setting
/cm { //cmmatrix astore concat } def
/i /setflat load def
/J /setlinecap load def
/d /setdash load def
/j /setlinejoin load def
/w /setlinewidth load def
/M /setmiterlimit load def
/gs { gs } def
end
% Each entry in this dictionary is
% <gsres> <value> -proc- <gsres>
/gsbg {
/BGDefault load resolvedefaultfnproc setblackgeneration
} bdef
/gsucr {
/UCRDefault load resolvedefaultfnproc setundercolorremoval
} bdef
/gstr {
dup type /arraytype eq {
{ oforce /TRDefault load resolvedefaultfnproc } forall
setcolortransfer
} {
/TRDefault load resolvedefaultfnproc settransfer
} ifelse
} bdef
/gsparamdict mark
/SA { setstrokeadjust }
/OP { 1 index /op known not { dup op } if OP }
% The PDF 1.3 specification says that the name /Default is only
% recognized for {BG,UCR,TR}2. However, PDF 1.3 files produced
% by Adobe Acrobat Distiller 4.0 for Windows use the name /Default
% with the older keys, so we have to implement this.
/BG { 1 index /BG2 known { pop } { gsbg } ifelse }
/UCR { 1 index /UCR2 known { pop } { gsucr } ifelse }
/TR { 1 index /TR2 known { pop } { gstr } ifelse }
/HT {
dup /Default eq {
pop .setdefaultscreen
} {
%****** DOESN'T IMPLEMENT THE STREAM CASE YET ******
resolvehalftone sethalftone
} ifelse
}
/HTP {
% HTP may be present even if this isn't a DPS interpreter.
/sethalftonephase where { pop aload pop sethalftonephase } { pop } ifelse
}
% PDF 1.3
/Font { aload pop Tf }
/LW { setlinewidth }
/LC { setlinecap }
/LJ { setlinejoin }
/ML { setmiterlimit }
/D { aload pop setdash }
/RI { ri }
/op { op }
/OPM { OPM }
/BG2 { gsbg }
/UCR2 { gsucr }
/TR2 { gstr }
/FL { setflat }
/SM {
% SM may be present even if this is only a Level 2 interpreter.
/setsmoothness where { pop setsmoothness } { pop } ifelse
}
% PDF 1.4
% All of these require the "transparency" feature in the interpreter.
/ca { ca }
/CA { CA }
/SMask { gssmask }
/AIS { AIS }
/BM { BM }
/TK { TK }
.dicttomark readonly def
/gs { % <gsres> gs -
Page /ExtGState rget {
% We keep the dictionary on the stack during the forall so that
% keys that interact with each other have access to it.
dup {
oforce exch gsparamdict exch .knownget { exec } { pop } ifelse
} forall pop
} if
} bdef
% ------ Transparency support ------ %
/gssmask {
dup /None eq {
pop null
} {
% Preprocess the SMask value into a parameter dictionary for
% .begintransparencymask, with added /BBox and /Draw keys.
mark exch % Stack: mark smaskdict
dup /S oget /Subtype exch 3 2 roll
% Stack: mark ... smaskdict
dup /BC knownoget { /Background exch 3 2 roll } if
dup /TR knownoget {
resolveidfnproc /TransferFunction exch 3 2 roll
} if
dup /G oget dup /BBox oget /BBox exch 4 2 roll
/.execmaskgroup cvx 2 packedarray cvx /Draw exch 3 2 roll
pop .dicttomark
} ifelse SMask
} bdef
% This procedure is called to actually render the soft mask.
/.execmaskgroup { % <masknum> <paramdict> <formdict> .execmaskgroup -
% Save our place in PDFfile, and do a gsave to avoid resetting
% the color space.
gsave PDFfile fileposition 4 1 roll
% We have to select the group's color space so that the
% background color will be interpreted correctly.
dup /Group oget /CS knownoget { csresolve setcolorspace } if
exch dup /BBox get aload pop .begintransparencymask {
dup /Resources knownoget { oforce } { 0 dict } ifelse
exch false resolvestream
.execgroup .endtransparencymask
} .internalstopped {
.discardtransparencymask stop
} if
PDFfile exch setfileposition grestore
} bdef
% Paint a Form+Group XObject, either for a transparency mask or for a Do.
/.execgroup { % <resdict> <stream> .execgroup -
gsave
1 .setopacityalpha 1 .setshapealpha
0 .inittransparencymask 1 .inittransparencymask
/Compatible .setblendmode
% Execute the body of the Form, similar to DoForm.
pdfopdict .pdfruncontext
grestore
} bdef
/.beginformgroup { % groupdict bbox .beginformgroup -
exch mark exch % bbox mark groupdict
dup /CS knownoget { csresolve setcolorspace } if
dup /I knownoget { /Isolated exch 3 2 roll } if
dup /K knownoget { /Knockout exch 3 2 roll } if
pop .dicttomark
% Stack: bbox paramdict
exch aload pop
.begintransparencygroup
} bdef
% .paintgroupform implements the Form PaintProc in the case where the
% Form XObject dictionary includes a Group key. See .paintform below.
/.paintgroupform { % <resdict> <stream> <formdict> .paintgroupform -
dup /Group oget exch /BBox oget
% Stack: resdict stream groupdict bbox
.beginformgroup {
.execgroup
} .internalstopped {
.discardtransparencygroup stop
} if .endtransparencygroup
} bdef
% Make an ImageType 103 (soft-masked) image.
/makesoftmaskimage { % <datasource> <imagemask> <SMask> makesoftmaskimage
% <datasource> <imagemask>, updates currentdict =
% imagedict
% See the ImageType 3 case of makemaskimage below.
% SMask is a stream, another Image XObject.
% Stack: datasource imagemask(false) smaskstreamdict
PDFfile fileposition exch
dup /Matte knownoget { /Matte exch def } if
dup length dict makeimagedict pop
% In order to prevent the two data sources from being
% aliased, we need to make at least one a reusable stream.
% We pick the mask, since it's smaller (in case we need to
% read all its data now).
% Stack: datasource imagemask(false) savedpos
% maskdict is currentdict
/DataSource DataSource mark
/Intent 1
/AsyncRead true
.dicttomark .reusablestreamdecode def
PDFfile exch setfileposition
currentdict end currentdict end
5 dict begin
/ImageType 103 def
/DataDict exch def
dup /InterleaveType 3 put
DataDict /Matte .knownget {
/Matte exch def
} if
AlphaIsShape { /ShapeMaskDict } { /OpacityMaskDict } ifelse exch def
/ColorSpace DataDict /ColorSpace get def
} bdef
% ---------------- Color setting ---------------- %
/01_1 [0 1] readonly def
/01_3 [0 1 0 1 0 1] readonly def
/01_4 [0 1 0 1 0 1 0 1] readonly def
% The keys here are resolved (PostScript, not PDF) color space names.
/csncompdict mark
/DeviceGray { pop 1 }
/DeviceRGB { pop 3 }
/DeviceCMYK { pop 4 }
/CIEBasedA { pop 1 }
/CIEBasedABC { pop 3 }
/ICCBased { 1 oget /N oget }
/Separation { pop 1 }
/DeviceN { 1 oget length }
.dicttomark readonly def
% Perhaps some of the values in the following need to be modified
% depending on the WhitePoint value....
/cslabinit mark
/DecodeABC [{16 add 116 div} bind {500 div} bind {200 div} bind]
/MatrixABC [1 1 1 1 0 0 0 0 -1]
/DecodeLMN [
{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse
0.9505 mul} bind
{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse
} bind
{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse
1.0890 mul} bind
]
.dicttomark readonly def
/csrdict mark
/DeviceGray {
/DefaultGray Page /ColorSpace rget { exch pop resolvecolorspace } if
}
/DeviceRGB {
/DefaultRGB Page /ColorSpace rget { exch pop resolvecolorspace } if
}
/DeviceCMYK { }
/CalGray {
1 oget 6 dict begin
dup /Gamma knownoget {
/exp load 2 packedarray cvx /DecodeA exch def
} if
dup /BlackPoint knownoget { /BlackPoint exch def } if
dup /WhitePoint knownoget { /WhitePoint exch def } if
pop [ /CIEBasedA currentdict end ]
}
/CalRGB {
1 oget 6 dict begin
dup /Gamma knownoget {
[ exch { /exp load 2 packedarray cvx } forall
] /DecodeABC exch def
} if
dup /Matrix knownoget { /MatrixABC exch def } if
dup /BlackPoint knownoget { /BlackPoint exch def } if
dup /WhitePoint knownoget { /WhitePoint exch def } if
pop [ /CIEBasedABC currentdict end ]
}
/CalCMYK {
pop /DeviceCMYK % not defined by Adobe
}
/Lab {
1 oget 6 dict begin
dup /Range knownoget not { [-100 100 -100 100] } if
[0 100 null null null null] dup 2 4 -1 roll putinterval
/RangeABC exch def
//cslabinit { def } forall
dup /BlackPoint knownoget { /BlackPoint exch def } if
dup /WhitePoint knownoget { /WhitePoint exch def } if
pop [ /CIEBasedABC currentdict end ]
}
/ICCBased {
PDFfile fileposition exch
dup dup 1 oget
mark exch { oforce } forall .dicttomark
dup dup true resolvestream
/ReusableStreamDecode filter /DataSource exch put
1 exch put
exch PDFfile exch setfileposition
} bind
/Separation {
aload pop exch oforce resolvecolorspace exch oforce resolvefnproc
4 array astore
}
/DeviceN {
0 4 getinterval % ignore attributes
aload pop 3 -1 roll oforce
3 -1 roll oforce resolvecolorspace
3 -1 roll oforce resolvefnproc
4 array astore
}
/Indexed {
aload pop 3 -1 roll oforce resolvecolorspace
% If the underlying space is a Lab space, we must scale
% the output of the lookup table as part of DecodeABC.
dup dup type /arraytype eq { 0 get } if /CIEBasedABC eq {
dup 1 get /DecodeLMN known {
1 get dup length dict copy
begin /DecodeABC [ 0 2 4 {
RangeABC 1 index 1 add get RangeABC 2 index get sub /mul load
RangeABC 3 index get /add load
DecodeABC 6 -1 roll 2 idiv get [ 6 1 roll aload pop ] cvx
} for ] def
/RangeABC //01_3 def
currentdict end /CIEBasedABC exch 2 array astore
} if
} if
3 1 roll
oforce dup type /stringtype ne {
% The color lookup table is a stream.
% Get its contents. Don't lose our place in PDFfile.
% Stack: /Indexed basespace hival lookup
PDFfile fileposition 5 1 roll true resolvestream
% Stack: filepos /Indexed basespace hival lookupstream
1 index 1 add
% Stack: filepos /Indexed basespace hival lookupstream len
3 index
dup dup type /arraytype eq { 0 get } if
//csncompdict exch get exec mul
string readstring pop
% Stack: filepos /Indexed basespace hival table
5 -1 roll PDFfile exch setfileposition
}
if 4 array astore
}
/Pattern {
dup type /nametype ne {
dup length 1 gt {
1 oget resolvecolorspace
/Pattern exch 2 array astore
} if
} if
}
.dicttomark readonly def
/cssubst { % <csname> cssubst <cspace'> true
% <csname> cssubst false
dup resolvecolorspace
dup 1 index ne { exch pop true } { pop pop false } ifelse
} bdef
/csnames mark
/DeviceGray dup /DeviceRGB dup /DeviceCMYK dup /Pattern dup
.dicttomark readonly def
/csresolve { % <csresourcename> csresolve <cspace>
dup Page /ColorSpace rget {
exch pop resolvecolorspace
} {
//csnames 1 index known not { /undefined cvx signalerror } if
} ifelse
} bdef
/resolvecolorspace { % <cspace> resolvecolorspace <cspace'>
dup dup type /arraytype eq { 0 get } if
//csrdict exch .knownget {
exec dup type /nametype ne { dup length 1 eq { 0 get } if } if
} {
csresolve
} ifelse
} bdef
/scresolve { % <c0> ... scresolve <multi>
% We can't really make sc[n] and SC[N] work, because
% the color space information isn't available at
% conversion time; so we hack it by assuming that
% all the operands on the stack are used, and that
% if the top operand is a name, it's a Pattern resource.
dup type /nametype eq
{ Page /Pattern rget { resolvepattern } { null } ifelse }
if
dup type /dicttype eq {
% Check the PaintType, if any (shading patterns don't
% have one).
dup /PaintType .knownget { 2 eq } { false } ifelse
} {
.pdfcount 1 gt
} ifelse
} bdef
/.pdfpaintproc { % <patdict> <resdict> .pdfpaintproc -
DEBUG { (%Begin PaintProc) = flush } if
% For uncolored patterns, we have to unbind the current
% color and color space before running the PaintProc.
% There's no harm in doing this for colored patterns,
% so for simplicity, we always do it.
PDFfile fileposition 3 1 roll
q
null sc1 null SC1
exch false resolvestream pdfopdict .pdfruncontext
Q
DEBUG { (%End PaintProc) = flush } if
PDFfile exch setfileposition
} bdef
/resolvepattern { % <patternstreamdict> resolvepattern <patterndict>
% Don't do the resolvestream now: just capture the data
% from the file if necessary.
dup length dict copy
dup /FilePosition .knownget {
1 index /File get dup fileposition 3 1 roll
% Stack: dict savepos pos file
dup 3 -1 roll setfileposition
dup 3 index /Length oget string readstring pop
% Stack: dict savepos file string
3 1 roll exch setfileposition
1 index /File 3 -1 roll put
dup /FilePosition undef
} if
dup /Shading knownoget {
resolveshading 1 index /Shading 3 -1 roll put
} if
dup /PaintProc [
% Bind the resource dictionary into the PaintProc.
2 index /Resources knownoget { oforce } { 0 dict } ifelse
/.pdfpaintproc cvx
] cvx put
DEBUG {
(%Pattern: ) print dup === flush
} if
} bdef
drawopdict begin
/g { /DeviceGray cssubst { cs sc1 } { g } ifelse } bdef
/rg { /DeviceRGB cssubst { cs sc* } { rg } ifelse } bdef
/k { k } bdef
/cs { csresolve cs } bdef
/sc { scresolve { sc* } { sc1 } ifelse } bdef
/scn /sc load def
/G { /DeviceGray cssubst { CS SC1 } { G } ifelse } bdef
/RG { /DeviceRGB cssubst { CS SC* } { RG } ifelse } bdef
/K { K } bdef
/CS { csresolve CS } bdef
/ri { ri } bdef
/SC { scresolve { SC* } { SC1 } ifelse } bdef
/SCN /SC load def
end
% ---------------- Paths ---------------- %
drawopdict begin
% Path construction
/m /moveto load def
/l /lineto load def
/c /curveto load def
/v { currentpoint 6 2 roll curveto } def
/y { 2 copy curveto } def
/re {
4 2 roll moveto exch dup 0 rlineto 0 3 -1 roll rlineto neg 0 rlineto
closepath
} def
/h /closepath load def
% Path painting and clipping
/n { n } def
/S { S } def
/s { s } def
/f { f } def
/f* { f* } def
/B { B } def
/b { b } def
/B* { B* } def
/b* { b* } def
/W { W } def
/W* { W* } def
/sh { resolvesh shfill } def
end
% ---------------- XObjects ---------------- %
/xobjectprocs mark % <dict> -proc- -
/Image { DoImage }
/Form { DoForm }
/PS { DoPS }
.dicttomark readonly def
% Note that the keys in defaultdecodedict are resolved (PostScript, not PDF)
% color space names.
/defaultdecodedict mark
/DeviceGray { pop //01_1 } bind
/DeviceRGB { pop //01_3 } bind
/DeviceCMYK { pop //01_4 } bind
/CIEBasedA { 1 get /RangeA .knownget not { //01_1 } if } bind
/CIEBasedABC { 1 get /RangeABC .knownget not { //01_3 } if } bind
/ICCBased {
1 oget dup /Range .knownget {
exch pop
}{
/N get [ exch {0 1} repeat ] readonly
} ifelse
} bind
/Separation { pop //01_1 } bind
/DeviceN {
1 oget length [ exch {0 1} repeat ] readonly
} bind
/Indexed {
pop [ 0 1 BitsPerComponent bitshift 1 sub ]
} bind
.dicttomark readonly def
/checkaltimage { % <resdict> checkaltimage <resdict[']>
Printed {
dup /Alternates knownoget {
{
dup /DefaultForPrinting knownoget {
{
/Image oget exch pop exit
} {
pop
} ifelse
} {
pop
} ifelse
} forall
} if
} if
} bdef
/makeimagedict { % <resdict> <newdict> makeimagedict <imagemask>
% On return, newdict' is currentdict
begin
/Width 2 copy oget def
/Height 2 copy oget def
/BitsPerComponent 2 copy oget def
/Interpolate 2 copy knownoget { def } { pop } ifelse
makeimagekeys
} bdef
/makeimagekeys { % <resdict> makeimagekeys <imagemask>
% newdict is currentdict
% Assumes Width, Height, BPC, Interpolate already copied.
/ImageType 1 def
/ImageMatrix Width 0 0
% Handle 0-height images specially.
Height dup 0 eq { pop 1 } if neg 0 1 index neg
6 array astore def
dup /ImageMask knownoget dup { and } if {
% Image mask
% Decode is required for the PostScript image operators.
% AI8 writes bogus decode array [0 1 0 0 0 0 0 0]
/Decode 2 copy knownoget { 0 2 getinterval } { //01_1 } ifelse def
% BitsPerComponent may be missing for masks.
% The spec requires it, but some producers omit it, and
% Acrobat Reader doesn't care.
/BitsPerComponent 2 copy known { pop } { 1 def } ifelse
true
} {
% Opaque image
dup /ColorSpace oget resolvecolorspace /ColorSpace exch def
% Decode is required for the PostScript image operators.
/Decode 2 copy knownoget not {
ColorSpace //defaultdecodedict
ColorSpace dup type /arraytype eq { 0 get } if get exec
} if def
false
} ifelse
% Even though we're going to read data,
% pass false to resolvestream so that
% it doesn't try to use Length (which may not be present).
exch false resolvestream /DataSource exch def
} bdef
/DoImage {
checkaltimage dup length 6 add dict
1 index /SMask knownoget { 1 index exch /SMask exch put } if
1 index /Mask knownoget { 1 index exch /Mask exch put } if
makeimagedict doimage
} bdef
/makemaskimage { % <datasource> <imagemask> <Mask> makemaskimage
% <datasource> <imagemask>, updates currentdict =
% imagedict
dup type /arraytype eq {
/ImageType 4 def
/MaskColor exch def
} {
% Mask is a stream, another Image XObject.
% Stack: datasource imagemask(false) maskstreamdict
PDFfile fileposition exch
dup length dict makeimagedict pop
% In order to prevent the two data sources from being
% aliased, we need to make at least one a reusable stream.
% We pick the mask, since it's smaller (in case we need to
% read all its data now).
% Stack: datasource imagemask(false) savedpos
% maskdict is currentdict
/DataSource DataSource mark
/Intent 1
/AsyncRead true
.dicttomark .reusablestreamdecode def
PDFfile exch setfileposition
currentdict end currentdict end
5 dict begin
/ImageType 3 def
/InterleaveType 3 def
/DataDict exch def
/MaskDict exch def
/ColorSpace DataDict /ColorSpace get def
} ifelse
} bdef
/doimage { % <imagemask> doimage -
% imagedict is currentdict, gets popped from dstack
DataSource exch
PDFversion 1.4 ge { currentdict /SMask knownoget } { false } ifelse {
makesoftmaskimage
} {
currentdict /Mask knownoget {
makemaskimage
} if
} ifelse
% Stack: datasource imagemask
% image and imagemask can be redefined in gs_init.ps to tweak interpolation
% after device-specific files are run. Don't bind them here.
{ currentdict end setfillstate /imagemask }
{ ColorSpace setcolorspace currentdict end setfillblend /image }
ifelse
.systemvar exec
% Close the input stream, unless it is PDFfile or
% PDFsource.
dup dup PDFfile eq exch PDFsource eq or { pop } { closefile } ifelse
} bdef
/.paintform { % <formdict> <resdict> <stream> .paintform -
3 -1 roll dup /Group known {
.paintgroupform
} {
pop pdfopdict .pdfruncontext
} ifelse
} bdef
/DoForm {
% Adobe 2nd edition of the PDF 1.3 spec makes /FormType
% and /Matrix keys optional. Cope with the missing keys.
dup length
1 index /Matrix known
{ dict
}
{ 1 add dict
dup /Matrix { 1 0 0 1 0 0 } cvlit put
}
ifelse
copy
dup /FormType known not {
dup length 1 add dict copy dup /FormType 1 put
} if
dup [ 2 index /Resources knownoget { oforce } { 0 dict } ifelse
3 index false /resolvestream cvx
/.paintform cvx
] cvx /PaintProc exch put
execform
} bdef
/DoPS {
true resolvestream cvx exec
} bdef
drawopdict begin
/Do {
setfillblend
PDFfile fileposition exch
dup Page /XObject rget {
exch pop dup /Subtype get xobjectprocs exch get
% Don't leave extra objects on the stack while executing
% the definition of the form.
3 -1 roll 2 .execn
} {
% This should cause an error, but Acrobat Reader can
% continue, so we do too.
(%stderr) (w) file
dup (****************Undefined XObject resource: ) writestring
dup 3 -1 roll write===
flushfile
} ifelse
PDFfile exch setfileposition
} bdef
end
% ---------------- In-line images ---------------- %
% Undo the abbreviations in an in-line image dictionary.
% Note that we must look inside array values.
% /I is context-dependent.
/unabbrevkeydict mark
/BPC /BitsPerComponent /CS /ColorSpace /D /Decode /DP /DecodeParms
/F /Filter /H /Height /I /Interpolate /IM /ImageMask /W /Width
.dicttomark readonly def
/unabbrevvaluedict mark
/AHx /ASCIIHexDecode /A85 /ASCII85Decode /CC /CalCMYK
/CCF /CCITTFaxDecode /CG /CalGray /CR /CalRGB
/DCT /DCTDecode /CMYK /DeviceCMYK /Fl /FlateDecode
/G /DeviceGray /RGB /DeviceRGB
/I /Indexed /LZW /LZWDecode /RL /RunLengthDecode
.dicttomark readonly def
/unabbrevtypedict mark
/nametype {
//unabbrevvaluedict 1 index .knownget { exch pop } if
}
/arraytype {
dup 0 1 2 index length 1 sub {
2 copy get unabbrevvalue put dup
} for pop
}
.dicttomark readonly def
/unabbrevvalue { % <obj> unabbrevvalue <obj'>
oforce //unabbrevtypedict 1 index type .knownget { exec } if
} bdef
drawopdict begin
/BI { mark } bdef
/ID {
counttomark 2 idiv dup 6 add dict begin {
exch //unabbrevkeydict 1 index .knownget { exch pop } if
exch unabbrevvalue def
} repeat pop
/File PDFsource def
currentdict makeimagekeys doimage
% The Adobe documentation says that the data following ID
% consists of "lines", and some PDF files (specifically, some files
% produced by PCL2PDF from Visual Software) contain garbage bytes
% between the last byte of valid data and an EOL.
% Some files (PDFOUT v3.8d by GenText) have EI immediately following
% the stream. Some have no EOL and garbage bytes.
% Therefore, we skip all bytes before EI or EOL
0
{ PDFsource read not { //true exit } if
dup 10 eq 1 index 13 eq or
{ pop PDFsource token pop /EI ne exit
}
if
exch 69 eq 1 index 73 eq and { //false exit } if % 'EI'
}
loop
exch pop
{ /ID cvx /syntaxerror signalerror
}
if
} bdef
end
% ================================ Text ================================ %
drawopdict begin
% Text control
/BT { BT } def
/ET { ET } def
/Tc { Tc } def
/TL { TL } def
/Tr { Tr } def
/Ts { Ts } def
/Tw { Tw } def
/Tz { Tz } def
% Text positioning
/Td { Td } def
/TD { TD } def
/Tm { Tm } def
/T* { T* } def
% Text painting
/Tj { Tj } def
/' { ' } def
/" { " } def
/TJ { TJ } def
end
% ============================== Annotations ============================== %
% Get and normalize an annotation's rectangle.
/annotrect { % <annot> annotrect <x> <y> <w> <h>
/Rect get aload pop
exch 3 index sub dup 0 lt { dup 5 -1 roll add 4 1 roll neg } if
exch 2 index sub dup 0 lt { dup 4 -1 roll add 3 1 roll neg } if
} bdef
% Set an annotation color.
/annotsetcolor { % <annot> annotsetcolor -
/C knownoget { aload pop setrgbcolor } { 0 setgray } ifelse
} bdef
% Draw the border. Currently, we ignore requests for beveling, and we
% don't round the corners of rectangles.
/strokeborder { % <annot> <width> <dash> strokeborder -
1 index 0 ne { % do not draw if border width is 0
gsave
2 index annotsetcolor
0 setdash dup setlinewidth
exch annotrect
2 { 4 index sub 4 1 roll } repeat
2 { 4 index 0.5 mul add 4 1 roll } repeat
rectstroke pop
grestore
} {
pop pop pop
} ifelse
} bdef
% Draw an annotation border.
/drawborder { % <annot> drawborder -
gsave
dup /BS knownoget {
dup /W knownoget not { 1 } if
[] 2 index /S knownoget {
/D eq { 2 index /D knownoget not { [3] } if exch pop } if
} if 3 -1 roll pop strokeborder
} {
dup /Border knownoget {
dup 2 get
exch dup length 3 gt { 3 get } { pop [] } ifelse
strokeborder
} {
pop
} ifelse
} ifelse
grestore
} bdef
%
% The PDF annotation F (flags) integer is bit encoded.
% Bit 1 (LSB) Invisible: 1 --> Do not display if no handler.
% Note: We have no handlers but we ignore this bit.
% Bit 2 Hidden: 1 --> Do not display. We will not display if this bit is set.
% Bit 3 Print: 1 --> Display if printing. We will display if this bit set
% (and not hidden) and Printed is true
% Bit 4 NoZoom: 1 --> Do not zoom annotation even if image is zoomed.
% Bit 5 NoRotate: 1 --> Do not rotate annotation even if image is rotated.
% Bit 6 NoView: 0 --> Display if this is a 'viewer'. We will display
% if this bit is not set (and not hidden) and Printed is false
% Bit 7 Read Only - 1 --> No interaction. We ignore this bit
%
/annotvisible { % <annot> annotvisible <visible>
/F knownoget not { 0 } if % Get flag value
dup 2 and 0 eq % Check hidden flag
exch dup 4 and 0 ne Printed and % Check print flag
exch 64 and 0 eq Printed not and % Check noview flag
or % Combine print and view
and % Combine with 'hidden' flag test
} bdef
/drawwidget { % <scalefactor> <annot> drawwidget -
dup /AP knownoget {
% Always use the Normal appearance.
/N oget
% Acrobat Distiller produces files in which this Form
% XObject lacks Type and Subtype keys. This is illegal,
% but Acrobat Reader accepts it. The only way we can
% tell whether this is a Form or a set of sub-appearances
% is by testing for the stream Length key.
dup /Length known {
% If this is a form then simply use it
true
} {
1 index /AS knownoget not {
% If we do not have AS then use any appearance
{ exch pop oforce exit } forall true
} {
% Stack: annot Ndict AS
% Get the specified appearance. If no appearance, then
% display nothing - set stack = false.
knownoget
} ifelse
} ifelse
% Stack: scale annot appearance true
% Stack: scale annot false
{
% Draw appearance
1 index annotrect pop pop translate
2 index dup scale % Apply scale factor
DoForm
} if
} if pop pop
} bdef
%
% For stamp object we have to determine the size of the output rectangle
% and the size of the BBox for the stamp image. From these we calculate
% a scale factor for drawing the stamp.
%
/calcstampscale { % <annot> calcstampscale scale
dup annotrect 4 -2 roll pop pop pop % get x width
dup 0 lt { neg } if % get magnitude
exch /AP knownoget {
/N knownoget {
/BBox knownoget {
aload pop 4 -2 roll pop pop pop
div
} {
pop 1 % default to unity scaling
} ifelse % if we have /BBox
} {
pop 1
} ifelse % if we have /N
} {
pop 1
} ifelse % if we have /AP
} bdef
/drawlink { % <annot> drawlink -
dup drawborder
1 exch drawwidget
} bdef
% Draw an annotation.
/drawannottypes mark
/Link { drawlink } bind
/Stamp { dup calcstampscale exch drawwidget } bind
.dicttomark readonly def
/drawannot { % <annot> drawannot -
dup annotvisible {
gsave
dup dup /Subtype get //drawannottypes exch .knownget {
exec
} {
1 exch drawwidget % Use drawwidget for everything else
} ifelse % type known
grestore
} if pop % annotvisible
} bdef
currentdict /drawannottypes undef
end % pdfdict
end % GS_PDF_ProcSet
.setglobal